home *** CD-ROM | disk | FTP | other *** search
/ Software Vault: The Gold Collection / Software Vault - The Gold Collection (American Databankers) (1993).ISO / cdr30 / blank_1.zip / BLANK.ASM next >
Assembly Source File  |  1993-05-01  |  33KB  |  733 lines

  1. PAGE        60,132
  2. NAME        Blank
  3. .MODEL      Small
  4. .CODE
  5.  
  6. GoInt       MACRO   Num                     ; Quick And Dirty
  7.             IF      ((.TYPE Num) AND 4)
  8.                 Int Num                     ; INT for constants
  9.                 Iret
  10.             ELSE
  11.                 Jmp SHORT Num               ; Jump to address
  12.                 Nop                         ; Align
  13.             ENDIF
  14.             ENDM
  15.  
  16. Inp         MACRO   Reg, Port               ; Used to FORCE a delay after I/O
  17.             In      Reg, Port
  18.             Jmp     SHORT @F
  19. @@:
  20.             ENDM
  21.  
  22. Outp        MACRO   Port, Reg               ; Used to FORCE a delay after I/O
  23.             Out     Port, Reg
  24.             Jmp     SHORT @F
  25. @@:
  26.             ENDM
  27.  
  28. IRQMapH     Equ     20h SHR 2       ; Rom set mapped address
  29. IRQMap      Equ     1E0h            ; Linear Address of 8259 IRQ Mapping
  30. IRQMapB     Equ     IRQMap SHR 2    ; Bits to direct the 8259 to Linear Map
  31. NumIRQ      Equ     8               ; Number of IRQ Masks
  32.  
  33.             Org     80h             ; Data storage for Local USE
  34. Stat        Db      ?               ; Video Status Byte
  35. ;----------------------------------------------------------------------------
  36. ; The following EQUs define the status Byte
  37. ;
  38. MDA         Equ     80h             ; Monochrome
  39. CGA         Equ     40h             ; Color Graphics Adapter
  40. EGA         Equ     20h             ; Enhanced Graphics Adapter
  41. VGA         Equ     10h             ; Video Graphics Array
  42. TwoMonitors Equ     08h             ; A second video Adapter was found
  43. TimeAct     Equ     04h             ; S = 8259 PIC is remapped
  44.                                     ; R = 8259 PIC in normal mode
  45. Enabled     Equ     02h             ; S = Screen is ACTIVE
  46.                                     ; R = Screen is DISABLED
  47. Quicky      Equ     01h             ; S = Resident code to blank video
  48.                                     ; R = Normal Timer Checks
  49. Second      Equ     01h             ; S = Found Resident Code
  50.                                     ; R = No Resident code found
  51. Stat1       Db      ?               ; Used for Second adapter Identifier
  52. Click       Equ     10h             ; S = Do a KeyClick with KeyMake
  53.                                     ; R = No KeyClick
  54. CtrlOn      Equ     08h             ; Control Key has been pressed
  55. EscOn       Equ     04h             ; The ESC key has been pressed
  56. EnterOn     Equ     02h             ; The Enter Key has been pressed
  57.  
  58. CtrlKey     Equ     1Dh             ; Scan code for the CTRL Key
  59. EnterKey    Equ     1Ch             ; Scan code for the Enter key
  60. EscKey      Equ     01h             ; Sacn Code for the ESC Key
  61.  
  62. MSR         Dw      ?               ; MSR for primary Adapter
  63. MSR1        Dw      ?               ; MSR for seconf adapter
  64. TimerTic    Dw      ?               ; Timer Tic Counter
  65. UsrTic      Dw      ?               ; Usr set maximum
  66. OneMin      Equ     1092            ; One minute of TICS
  67. FiveMins    Equ     OneMin*5        ; Five minutes of TICS
  68. MaxMin      Equ     9               ; Nine maximum minutes
  69. MaxTics     Equ     OneMin*MaxMin   ; Nine minutes maximum time allowed
  70.  
  71. MSRV        Db      8 DUP (?)       ; Video - MSR enable values
  72. OldInt8     Dd      ?               ; Original INT Vector
  73.  
  74. CPUType     Dw      ?               ; Type of CPU - 86/286/386
  75. NDPType     Dw      ?               ; Type of NDP - 87/287/387
  76.  
  77.             Org     100h            ; Start of Logic
  78. Main        PROC    FAR
  79.             ASSUME  Cs:@code, Ds:@code, Es:@code
  80. Machine     LABEL   BYTE
  81.             Jmp     Init            ; Do the Initialization
  82. Signature   Db      'BLANK V1.0 - April 1, 1989',0
  83. SigLen      Equ     $-Signature     ; Character size
  84.  
  85. NewLLInt    PROC    NEAR
  86.             GoInt   8
  87.             GoInt   LLInt9          ; Jump to the IRQ 1 Handler - KEYPRESS
  88.             GoInt   10
  89.             GoInt   11
  90.             GoInt   12
  91.             GoInt   13
  92.             GoInt   14
  93.             GoInt   15
  94. LLInt9:
  95.             Cli                     ; Disable INTR
  96.             Push    Ax              ; Save registers
  97.             Push    Bx
  98.             Push    Cx
  99.             Push    Dx
  100.             Push    Ds
  101.  
  102.             Push    Cs              ; Set local coverage
  103.             Pop     Ds
  104.             Inp     Al,60h          ; Read the KBD
  105.             Test    Al,80h          ; Is this KEY Release
  106.             Jnz     ChkCtrl         ; Yes - Then Skip the CLICK
  107.             Test    Stat1,Click     ; Do a KeyClick
  108.             Jz      ChkCtrl         ; No
  109.             Push    Ax              ; Save Byte
  110.             Mov     Al,0BFh         ; Set clock rate
  111.             Outp    43h,Al          ; for clock 2
  112.             Mov     Al,04Bh
  113.             Outp    42h,Al
  114.             Mov     Al,0Fh
  115.             Outp    42h,Al
  116.             Inp     Al,61h          ; read the port
  117.             Mov     Ah,Al           ; save data for restore
  118.             Or      Al,3h           ; enable the speaker gate
  119.             Outp    61h,Al
  120.             Mov     Cx,100h         ; Set TIME for GATE 2 Open
  121. @@:
  122.             Loop    @B              ; loop to myself
  123.             Mov     Al,Ah           ; restore data
  124.             Outp    61h,Al
  125.             Pop     Ax              ; Restore Byte
  126. ChkCtrl:
  127.             Cmp     Al,CtrlKey      ; Is this The Control Key ?
  128.             Jnz     ChkEsc          ; No - Check for the ESC Key
  129.             Or      Stat1,CtrlOn    ; Set the Control Key has been Pressed
  130.             Jmp     SHORT ClearCtr  ; Now check the Screen TIMEOUT
  131. ChkEsc:
  132.             Cmp     Al,EscKey       ; IS this the ESC Key
  133.             Jnz     ChkClick        ; No - Check for Click Toggle
  134.             Or      Stat1,EscOn     ; Set ESC has been pressed
  135.             Jmp     SHORT ClearCtr  ; Ok - now clear the counter
  136. ChkClick:
  137.             Cmp     Al,EnterKey     ; Click Toggle Key
  138.             Jnz     ClearKeys       ; No
  139.             Or      Stat1,EnterOn   ; Yes - then set for check
  140.             Jmp     SHORT ClearCtr  ; Now clear the TIMER Count
  141. ClearKeys:
  142.             And     Stat1,NOT (EscOn OR CtrlOn OR EnterOn)
  143. ClearCtr:
  144.             Xor     Ax,Ax           ; Ok, Key was pressed - Clear
  145.             Mov     TimerTic,Ax     ;   the counter
  146.  
  147.             Mov     Al,Stat1        ; Get the Status Byte
  148.             And     Al,EscOn OR CtrlOn
  149.             Cmp     Al,EscOn OR CtrlOn  ; Is this a QUICK Blank?
  150.             Jnz     Chain9          ; No - then Exit
  151.             Or      Stat,Quicky     ; Set for Quick Blank Of the Video
  152.             Xor     Stat1,Quicky    ; Reset BIT
  153. IgnoreKey:
  154.             Mov     Al,0E1h         ; Ack 8259 For IRQ1
  155.             Outp    20h,Al          ; Send the Ack
  156.             Inp     Al,61h          ; Now reset the KBD
  157.             Mov     Ah,Al           ; Save current Status
  158.             Or      Al,80h          ; Enable sensw
  159.             Outp    61h,Al
  160.             Mov     Al,Ah           ; Restore Status
  161.             And     Al,7Fh          ; Enable KBD
  162.             Outp    61h,Al
  163.             Pop     Ds              ; Restore registers
  164.             Pop     Dx
  165.             Pop     Cx
  166.             Pop     Bx
  167.             Pop     Ax
  168.             Iret
  169. Chain9:
  170.             Mov     Al,Stat1        ; Get the Status Byte
  171.             And     Al,CtrlOn OR EnterOn
  172.             Cmp     Al,CtrlOn OR EnterOn ; Is this a Click Toggle
  173.             Jnz     Chain91         ; No - then Check QUICK Blank
  174.             Xor     Stat1,Click     ; Toggle Click'ing
  175.             Jmp     IgnoreKey       ; Ignore the KeyMake
  176. Chain91:
  177.             Test    Stat1,Quicky    ; In QUICK BLANK Mode
  178.             Jnz     IgnoreKey       ; Yes - then Exit
  179.             Test    Stat,Enabled    ; Is the Screen Active
  180.             Jnz     LLIExit         ; Yes - then pass to next
  181.             Test    Stat,EGA OR VGA ; Enhanced videos
  182.             Jz      DoMDCGA         ; No
  183.             Mov     Al,20h          ; Enable the EGA/VGA
  184.             Call    DoEVGA
  185.             Jmp     SHORT LLI9Exit1 ; and get out
  186. DoMDCGA:
  187.             Push    Ds              ; Save
  188.             Xor     Ax,Ax           ; Set to SEG=0
  189.             Mov     Ds,Ax
  190.             Mov     Al,Ds:[449h]    ; Get Current Mode
  191.             Pop     Ds              ; Restore
  192.             Mov     Dx,MSR          ; Get the primary MSR
  193.             Lea     Bx,MSRV         ; Point to Xlate table
  194.             Xlat    MSRV            ; Translate to proper enable Value
  195.             Outp    Dx,Al           ; VIDEO IS NOT ACTIVE
  196. LLI9Exit1:
  197.             Mov     Al,29h          ; Set for Enable
  198.             Call    Adapter2        ; Enable it if present
  199.             Or      Stat,Enabled    ; Display is now active
  200. LLIExit:
  201.             Pop     Ds              ; Restore registers
  202.             Pop     Dx
  203.             Pop     Cx
  204.             Pop     Bx
  205.             Pop     Ax
  206.             Int     9               ; CHAIN to INT 9
  207.             Iret
  208. NewLLInt    ENDP
  209.  
  210. NewInt8     PROC    NEAR
  211.             Sti                     ; Enable INTR
  212.             Pushf                   ; fake INTR to chained links
  213.             Call    DWORD PTR Cs:OldInt8
  214.  
  215.             Cmp     Ax,-1           ; Check for Chained Load Checking
  216.             Jnz     NewInt81        ; Noop
  217.             Cmp     Bx,-2           ; Check Again
  218.             Jnz     NewInt81        ; Noop
  219.             Cmp     Cx,-3           ; Check again
  220.             Jnz     NewInt81        ; Noop
  221.             Cmp     Dx,-4           ; This should be enough Checking
  222.             Jnz     NewInt81        ; Noop
  223.             Push    Cs              ; Must Reture Segment in ES
  224.             Pop     Es
  225.             Jmp     SHORT I8Exit    ; Back to Caller
  226. NewInt81:
  227.             Test    Cs:Stat,TimeAct ; Are we disabled
  228.             Jnz     Update          ; No then update the counter
  229. I8Exit:
  230.             Iret                    ; Just Exit
  231. Update:
  232.             Push    Ax              ; Save registers
  233.             Push    Bx
  234.             Push    Dx
  235.             Push    Ds
  236.  
  237.             Push    Cs
  238.             Pop     Ds              ; Get Local Coverage
  239.             Test    Stat,Quicky     ; Perform a QUICKY?
  240.             Jz      NormTime        ; No
  241.             And     Stat,NOT Quicky ; Clear BIT
  242.             Jmp     SHORT QuickBlank; Do it FRED
  243. NormTime:
  244.             Test    Stat,Enabled    ; is the screen active
  245.             Jz      TExit           ; No - then do not check
  246.             Inc     TimerTic        ; Add to counter
  247.             Mov     Ax,TimerTic     ; have we reachewd our limit?
  248.             Cmp     Ax,UsrTic       ; Get usr set maximum
  249.             Jb      TExit           ; No - then Exit
  250. QuickBlank:
  251.             And     Stat,NOT Enabled; set disabled
  252.             Test    Stat,EGA OR VGA ; is this an EGA/VGA
  253.             Jnz     DoSpecial       ; Yes
  254.             Mov     Dx,MSR          ; Get the Primary MSR
  255.             Mov     Al,25h          ; Disable for MDA/CGA
  256.             Outp    Dx,Al
  257.             Jmp     SHORT TExit1    ; Set screen is disabled
  258. DoSpecial:
  259.             Xor     Al,Al           ; Disable the EVGA
  260.             Call    DoEVGA          ; Blank out the EGA/VGA Screen
  261. TExit1:
  262.             Mov     Al,25h          ; Set Disable Code
  263.             Call    Adapter2        ; Check for second adapter
  264. TExit:
  265.             Pop     Ds              ; Restore registers
  266.             Pop     Dx
  267.             Pop     Bx
  268.             Pop     Ax
  269.             Jmp     I8Exit          ; Back to the shadows
  270. NewInt8     ENDP
  271.  
  272. DoEVGA      PROC    NEAR
  273.             Push    Ax              ; Save Command code
  274.             Push    Ds              ; Save DS
  275.             Xor     Ax,Ax           ; set to segment = 0
  276.             Mov     Ds,Ax
  277.             Mov     Al,Byte Ptr Ds:[465h] ; Get current 6845 MSR value
  278.             Mov     Bx,Word Ptr Ds:[463h] ; Get current CRT I/O Port
  279.             Pop     Ds              ; Restore Coverage
  280.             Add     Bx,6            ; Set to Status Register
  281.             Mov     Dx,3CDh         ; Assume EGA for now
  282.             Inp     Al,Dx
  283.             Mov     Ah,Al           ; Save current video State
  284.             And     Al,67h
  285.             Outp    Dx,Al
  286.             Mov     Dx,Bx           ; Set to Current CRT IO Port
  287.             Inp     Al,Dx           ; Read current video Status
  288.             Pop     Bx              ; Restore Function 0=Disable 20=Enable
  289.             Mov     Al,Bl
  290.             Mov     Dx,3C0h         ; Video Attributes Register
  291.             Outp    Dx,Al           ; BLANK THE SCREEN
  292.             Mov     Al,Ah           ; Restore CRT Status
  293.             And     Al,0EFh         ; Strip off Bit 5
  294.             Mov     Dx,3CDh
  295.             Outp    Dx,Al
  296.             Ret                     ; Back to the caller
  297. DoEVGA      ENDP
  298.  
  299. Adapter2    PROC    NEAR
  300.             Test    Stat,TwoMonitors; Do we have 2 videos
  301.             Jz      A2Exit          ; No - then Exit
  302.             Mov     Dx,MSR1         ; Get MSR for secondary Adapter
  303.             Outp    Dx,Al           ; Send command
  304. A2Exit:
  305.             Ret
  306. Adapter2    ENDP
  307.  
  308. Init:                               ; Initialization Routine
  309.             Mov     Ax,Cs           ; Ensure DOS covers us on initialization
  310.             Mov     Ds,Ax
  311.             Mov     Es,Ax
  312.             Lea     Dx,Message      ; Display ownership message
  313.             Mov     Ah,9
  314.             Int     21h
  315.  
  316.             Push    Es
  317.             Mov     Ax,0F000h       ; Get machine type ID
  318.             Mov     Es,Ax
  319.             Mov     Al,Byte Ptr Es:[0FFFEh]
  320.             Pop     Es
  321.             Mov     Machine,Al      ; Save Machine ID
  322.  
  323. ; Initialize parameters
  324.  
  325.             Lea     Si,Stat         ; Point to the Parameter Table
  326.             Cmp     Byte Ptr [Si],0 ; Check for any parameter value
  327.             Jz      Default         ; Ok - use default
  328.             Inc     Si              ; Bump to the first character
  329. ParmIn:
  330.             Lodsb                   ; Get parameter count
  331.             Cmp     Al,20h          ; Is this a space
  332.             Jz      ParmIn          ; Yes - then ignore
  333.             Cmp     Al,9h           ; Is this a TAB
  334.             Jz      ParmIn          ; Yes - then SKIP it
  335.             Cmp     Al,0Dh          ; End of Input
  336.             Jz      Default         ; Yes - then use default value
  337.             Xor     Al,30h          ; Strip off ASCII
  338.             Cbw                     ; Strip upper half of word
  339.             Or      Al,Al           ; Anything Passed
  340.             Jz      ChkDis          ; No - then check for disable
  341.             Cmp     Al,MaxMin       ; Above Maximum
  342.             Ja      Default         ; To high - set default
  343.             Jmp     SHORT SetTime   ; Calculate TICS
  344. ChkDis:
  345.             Call    CheckMap        ; Are we already resident - ES has Res Vector
  346.             Jc      NoGo            ; Can not disable - not loaded
  347.  
  348.             Call    GetCpu          ; Get CPU Type
  349.             Mov     CPUType,Ax      ; And save
  350.             Call    GetNdp          ; Get NDP if any
  351.             Mov     NDPType,Ax      ; And Save
  352.             And     Es:Stat,NOT TimeAct ; Set disable switch
  353.             Mov     Bl,IRQMapH      ; Set Vector for 8259
  354.             Call    SetMap          ; Remap the 8259
  355.             Sti                     ; Enable INTR
  356.             Lea     Dx,Disabled     ; Show Disabled
  357.             Mov     Ah,9
  358.             Int     21h
  359. Norm:
  360.             Mov     Ax,4C00h        ; Terminate normally
  361.             Int     21h
  362. NoGo:
  363.             Lea     Dx,NotLoaded    ; We are not loaded
  364.             Mov     Ah,9
  365.             Int     21h
  366. Term:
  367.             Mov     Ax,4C01h        ; Exit with error
  368.             Int     21h
  369. SetTime:
  370.             Mov     Cx,OneMin       ; Get TICS per minute
  371.             Mul     Cx              ; Convert to TICS
  372.             Jmp     SHORT SetTICS   ; Save off tics wanted
  373. Default:
  374.             Mov     Ax,FiveMins     ; Set default to FIVE Minutes
  375. SetTICS:
  376.             Mov     UsrTic,Ax       ; Save in local storage
  377.             Mov     TimerTic,0      ; Initialize Current TIC Counter
  378.             Mov     Stat,0
  379.             Mov     Stat1,0
  380.  
  381.             Call    GetCpu          ; Get CPU Type
  382.             Mov     CPUType,Ax      ; And save
  383.             Call    GetNdp          ; Get NDP if any
  384.             Mov     NDPType,Ax      ; And Save
  385.  
  386.             Lea     Di,MSRV         ; Point to Local storage
  387.             Lea     Si,MSRValues    ; Table of NSR Values
  388.             Mov     Cx,LenMSRV      ; Get count
  389.             Rep     Movsb           ; Copy to local storage
  390.  
  391.             Lea     Di,WorkBuf      ; Point to Storage Area
  392.             Xor     Bx,Bx           ; Clear for Call
  393.             Mov     Ax,1B00h        ; Check for a VGA
  394.             Int     10h             ; Video BIOS call
  395.             Cmp     Al,1Bh          ; Is this a VGA
  396.             Jnz     ChkEGA          ; No - then check for other
  397.             Mov     Al,VGA          ; Set for VGA
  398.             Jmp     SHORT SetVideo  ; now - mov the local to resident
  399. ChkEGA:
  400.             Mov     Ah,12h          ; EGA Status check
  401.             Mov     Bl,10h
  402.             Xor     Cx,Cx           ; Clear the status bits
  403.             Int     10h             ; Video BIOS Call
  404.             Jcxz    NoEGA           ; Now check for MDA/CGA
  405.             Mov     Al,EGA          ; Set for EGA
  406.             Jmp     SHORT SetVideo  ; Set video type
  407. NoEGA:
  408.             Mov     Ah,0Fh          ; Get Current Video Mode
  409.             Int     10h
  410.             Cmp     Al,7            ; Is a monochrome?
  411.             Je      SetMono         ; Yes
  412.             Cmp     Al,15           ; Graphic Mono
  413.             Je      SetMono         ; Yes
  414.             Mov     Al,CGA          ; no - its a CGA
  415.             Mov     Dx,3D8h         ; Set CGA MSR
  416.             Jmp     SHORT SetVideo  ; Save in local storage
  417. SetMono:
  418.             Mov     Al,MDA          ; Set for Mono
  419.             Mov     Dx,3B8h         ; Set MONO MSR
  420. SetVideo:
  421.             Mov     Stat,Al         ; Set type of Video
  422.             Mov     MSR,Dx          ; Save for Resident code
  423.  
  424. ;----------------------------------------------------------------------------
  425. ; Determine if a second video adapter is present
  426.             Mov     Dx,3D4h         ; Assume CGA attached
  427.             Push    Ds              ; Save
  428.             Xor     Ax,Ax           ; Clear
  429.             Mov     Ds,Ax           ; Set SEG=0
  430.             Cmp     Dx,Ds:[463h]    ; Is this a CGA ?
  431.             Pop     Ds              ; Restore
  432.             Jnz     Save_Second     ; No - then already set for CGA
  433.             Mov     Dx,3B4h         ; Yes, look for MDA
  434. Save_Second:
  435.             Mov     Al,0Fh          ; Select cursor low
  436.             Outp    Dx,Al
  437.             Inc     Dx              ; Get initial value for reset
  438.             Inp     Al,Dx
  439.             Mov     Ah,Al           ; And save it
  440. Find_Second:
  441.             Mov     Al,55h          ; Write first pattern
  442.             Outp    Dx,Al
  443.             Inp     Al,Dx           ; Read pattern back
  444.             Cmp     Al,55h          ; Is pattern same?
  445.             Jnz     No_Second       ; No, adapter not there
  446.             Mov     Al,0AAh         ; Write second pattern
  447.             Outp    Dx,Al
  448.             Inp     Al,Dx           ; Read pattern back
  449.             Cmp     Al,0AAh         ; Is pattern same?
  450.             Jnz     No_Second       ; No, adapter not there
  451.             Mov     Cl,TwoMonitors  ; Yes, set status bits
  452.             Jmp     SHORT GSADone   ; Finished
  453. No_Second:
  454.             Xor     Cl,Cl           ; Sorry, but you only have ONE monitor
  455. GSADone:
  456.             Mov     Al,Ah           ; Restore cursor info
  457.             Outp    Dx,Al
  458.             Add     Dx,3            ; Set to MSR of appropriate monitor
  459.             Or      Stat,Cl         ; Save 2nd monitor info
  460.             Or      Cl,Cl           ; Check if found for message display
  461.             Jz      CopyStorage
  462.             Cmp     Dx,3D8h         ; Is the Monitor a CGA
  463.             Jz      TwoCGA          ; Yes
  464.             Or      Stat1,MDA       ; No Second monitor is a MDA
  465.             Jmp     SHORT TwoShow
  466. TwoCGA:
  467.             Or      Stat1,CGA       ; Set 2nd adapter is a CGA
  468. TwoShow:
  469.             Mov     MSR1,Dx         ; Save MSR
  470.             Lea     Dx,TwoMons      ; Point to the messgae
  471.             Mov     Ah,9
  472.             Int     21h
  473. CopyStorage:
  474.             Mov     Ax,UsrTic       ; Get the number of TICS
  475.             Mov     Cx,OneMin       ; Number of tics per minute
  476.             Xor     Dx,Dx           ; Clear for Divide
  477.             Div     Cx
  478.             Or      Al,30h          ; Make ASCII
  479.             Mov     Minute,Al       ; Svae in the string
  480.             Lea     Dx,TimeOut
  481.             Mov     Ah,9
  482.             Int     21h
  483.  
  484. ;-----------------------------------------------------------------------------
  485. ; Now we must check to see if we are already Resident or not.
  486. ; If we are, then the new Timer value is passed to the resident code.
  487. ; Note - A value of ZERO will Disable the BLANK Program
  488. ;
  489.             Call    CheckMap        ; Check for Loaded Status
  490.             Jc      ReVector        ; Not loaded - Must revector
  491.             Mov     Al,Stat         ; Get Current Status and pass to res code
  492.             Mov     Es:Stat,Al
  493.             Mov     Ax,MSR          ; Pass Current MSR to Res Code
  494.             Mov     Es:MSR,Ax
  495.             Mov     Ax,MSR1         ; Secondary MSR to Res Code
  496.             Mov     Es:MSR1,Ax
  497.             Xor     Ax,Ax           ; Clear current Count
  498.             Mov     Es:TimerTic,Ax
  499.             Mov     Ax,UsrTic       ; Get the New TICS
  500.             Mov     Es:UsrTic,Ax    ; and put into the resident code
  501.             Mov     Stat,Second     ; And save in local
  502.             Jmp     SHORT ReMap     ; No - then setup 8259 PIC mapping
  503. PassTic:
  504.             Lea     Dx,ParmPass     ; Set parameters Passed
  505.             Mov     Ah,9
  506.             Int     21h
  507.             Jmp     Norm            ; And Exit
  508. ReVector:
  509.             Mov     Ax,3508h        ; Get INT 8 Vector
  510.             Int     21h
  511.             Cli
  512.             Mov     Word Ptr OldInt8 +0,Bx  ; Save offset
  513.             Mov     Word Ptr OldInt8 +2,Es  ; Save segment
  514.             Sti
  515.             Lea     Dx,NewInt8      ; Point to My Handler
  516.             Mov     Ax,2508h        ; Set INT VEctor
  517.             Int     21h             ; Now legal with DOS
  518.  
  519.             Xor     Ax,Ax           ; Set to Segment 0
  520.             Mov     Ds,Ax
  521.             Mov     Si,IRQMap       ; Get MAP address
  522.             Mov     Ax,OFFSET NewLLInt ; Address of my coding
  523.             Mov     Cx,NumIRQ       ; Set Loop Counter
  524.             Cli                     ; Ok Disable INTR
  525. IRQLoop:
  526.             Mov     [Si + 0],Ax     ; Address of IRQ offset
  527.             Mov     [Si + 2],Cs     ; Address of IRQ segment
  528.             Add     Ax,3            ; Point to the Next IRQ Mask Handler
  529.             Add     Si,4            ; Bump to Next IRQ Address
  530.             Loop    IRQLoop         ; Finish the Masks
  531. ReMap:
  532.             Mov     Ax,Cs           ; Restore Local Coverage
  533.             Mov     Ds,Ax
  534.             Mov     Bl,IRQMapB      ; Set 8259 Vector Address
  535.             Call    SetMap          ; Map the 8259
  536.  
  537.             Test    Stat,Second     ; Is this for already resident code
  538.             Jz      NewLoad         ; No
  539.             Or      Es:Stat,TimeAct OR Enabled
  540.             Jmp     PassTic         ; Exit normal
  541. NewLoad:
  542.             Or      Stat,TimeAct OR Enabled ; Set initial status
  543.             Or      Stat1,Click     ; Set KeyClick on KeyMake
  544.             Lea     Dx,ResMsg       ; Show resident message
  545.             Mov     Ah,9
  546.             Int     21h
  547.  
  548.             Lea     Dx,Init + 15    ; Address of End of Resident Code
  549.             Mov     Cl,4
  550.             Shr     Dx,Cl
  551.             Mov     Ax,3100h
  552.             Int     21h
  553.  
  554. CheckMap    PROC    NEAR
  555.             Xor     Ax,Ax           ; Get segment 0 Coverage
  556.             Mov     Ds,Ax
  557.             Les     Bx,DWORD PTR Ds:[IRQMap]
  558.             Push    Cs              ; Restore local coverage
  559.             Pop     Ds
  560.             Lea     Si,Signature    ; Point to My Signature
  561.             Mov     Di,Si           ; Should be the same in resident Coding
  562.             Mov     Cx,SigLen       ; how many characters for compare
  563.             Repz    Cmpsb           ; Is this My coding
  564.             Jnz     NotMe           ; Not me
  565.             Clc                     ; Set mapping was found
  566.             Ret                     ; And exit
  567. NotMe:
  568.             Mov     Ax,Es           ; Check for Zeor segment
  569.             Or      Ax,Ax           ; to see if anyone else has this INterrupt
  570.             Jz      NotMe1          ; No one else found
  571.             Push    Cs              ; For compare when return from INT
  572.             Pop     Es
  573.             Mov     Ax,-1           ; Setup for internal checking
  574.             Mov     Bx,-2
  575.             Mov     Cx,-3
  576.             Mov     Dx,-4
  577.             Int     8               ; Use the Normal H/W Timer
  578.             Mov     Ax,Cs
  579.             Mov     Bx,Es
  580.             Or      Ax,Bx           ; Is this Us
  581.             Jz      NotMe1          ; No exit
  582.             Clc                     ; Yes - then ES =
  583.             Ret
  584. NotMe1:
  585.             Stc                     ; We are not loaded
  586.             Ret                     ; Back to caller
  587. CheckMap    ENDP
  588.  
  589. SetMap      PROC    NEAR
  590.             Cli
  591.             Inp     Al,21h          ; Get Curent IMR
  592.             Push    Ax              ; And save for a restore
  593.             Mov     Al,0FFh
  594.             Outp    21h,Al
  595.             Mov     Cl,Machine      ; Get the Machine ID
  596.             Cmp     Cl,0F8h         ; Model 80
  597.             Jz      SetMap2         ; Yes - has 2 8259s
  598.             Cmp     Cl,0FCh         ; AT Type?
  599.             Jz      SetMap2         ; Yes - has 2 8259s
  600.             Mov     Al,13h          ; Set ICW1
  601.             Outp    20h,Al          ; Init the 8259
  602.             Mov     Al,Bl           ; Get ReMapped Address
  603.             Outp    21h,Al          ; Set New Address
  604.             Mov     Al,9h           ; Skip the ICW3 and DO ICW4
  605.             Outp    21h,Al          ; The 8259 is remapped
  606.             Jmp     SHORT SMExit    ; Now exit
  607. SetMap2:
  608.             Mov     Al,11h          ; Set ICW1 for MASTER/SLAVE Mode
  609.             Outp    20h,Al          ; To set IRQ address into My Coding
  610.             Mov     Al,Bl           ; Remapped Address
  611.             Outp    21h,Al          ; ICW2 - Vectored Address from BL
  612.             Mov     Al,4h           ; ICW3 - Set Slave Mapped to IR2 on Master
  613.             Outp    21h,Al
  614.             Mov     Al,1            ; OCW4 - Set 8259 PIC to iAPX86/88 Mode
  615.             Outp    21h,Al
  616. SMExit:
  617.             Pop     Ax              ; Restore Original Mask - IMR
  618.             Outp    21h,Al          ; And reset the mask bits
  619.             Sti
  620.             Ret                     ; Back to Caller
  621. SetMap      ENDP
  622.  
  623. GetCpu      PROC    NEAR
  624.             Pushf                   ; Save FLAG registers
  625.             Xor     Ax,Ax           ; Clear AX and push onto the stack.
  626.             Push    Ax
  627.             Popf                    ;  Pop a zero into FLAGs register
  628.             Pushf                   ;  Attempt to set bit 12-15 to a zero
  629.             Pop     Ax              ;  Recover FLAG word
  630.             And     Ax, 0F000h      ;  If Bits 12-15 are set then the processor
  631.             Cmp     Ax, 0F000h      ;  is an 8018x or an 808x
  632.             Jz      is801x
  633.             Mov     Ax,0F000h       ;  Try to set FLAG bits 12-14 (NT, IOPL)
  634.             Push    Ax
  635.             Popf                    ;  put 07000H into flags
  636.             Pushf
  637.             Pop     Ax
  638.             And     Ax,0F000h       ;  if bits 12-14 are cleared then the
  639.             Jz      is80286         ;       processor is an 286
  640. is80386:                            ;   Else it is a 386
  641.             Mov     Ax,386h
  642.             Jmp     Short GCExit    ; Exit
  643. is80286:
  644.             Mov     Ax,286h         ;  return 286 in AX
  645.             Jmp     Short GCExit    ; Get Out
  646. is801x:                             ; It is a 8086, a 80186, or a V20/V30
  647.             Mov     Ax,0FFFFh       ;  Set AX to all 1s
  648.             Mov     Cl,33           ;  Will shift it 33 times if it is an
  649.                                     ;  808x, or 1 time if it is an 8018x.
  650.             Shl     Ax,Cl           ;  If we shift 33 times all bits are
  651.             Jnz     is80186         ;  zero. If any bits are on it's an 18x
  652. is8086:                             ;  Else we have an 8086 or V20/V30.
  653.             Xor     Al,Al           ;  Sets ZF
  654.             Mov     Al,40h          ;  64 decimal
  655.             Mul     Al              ;  64**2 > 255
  656.             Jz      isv30           ;  V20/V30 MUL leaves ZF untouched
  657.                                     ;  8086 ZF==OF after MUL
  658.             Mov     Ax,86h          ;  Return 86/V20
  659.             Jmp     Short GCExit
  660. isv30:
  661.             Mov     Ax,30h          ;  Return V30
  662.             Jmp     Short GCExit
  663. is80186:
  664.             Mov     Ax,186h         ;  Return 186
  665. GCExit:
  666.             Popf                    ; Restore flags
  667.             Ret
  668. GetCpu      ENDP
  669.  
  670. ControlB    Equ     Byte Ptr [Bp - 2]
  671. ControlW    Equ     Word Ptr [Bp - 2]
  672.  
  673. GetNdp      PROC    NEAR
  674.             Push    Bp              ; Setup local storage
  675.             Mov     Bp,Sp
  676.             Mov     ControlW,0      ; Initialize storage
  677.             Fninit                  ; try to initialize NDP
  678.             Fnstcw  ControlW        ; put control word in mem
  679.             Mov     Ah,ControlB     ; if AH is 03h, you got
  680.             Cmp     Ah,03h          ;     an NDP on board !!
  681.             Jz      Chk87           ; found somethin', keep goin'
  682.             Xor     Ax,Ax           ; no processor found
  683.             Jmp     Short NdpExit   ; retunr
  684. Chk87:
  685.             And     ControlW,NOT 0080h  ; turn ON interrupts (IEM=0)
  686.             Fldcw   ControlW        ; load control word
  687.             Fdisi                   ; turn OFF interrupts (IEM=1)
  688.             Fstcw   ControlW        ; store control word
  689.             Test    ControlB,80h    ; iff IEM=1, 8087
  690.             Jz      Chk287          ; guess not!  March on....
  691.             Mov     Ax,87h          ; this is an 8087
  692.             Jmp     Short NdpExit
  693. Chk287:
  694.             Finit                   ; set default infinity mode
  695.             Fld1                    ; make infinity
  696.             Fldz                    ;     by dividing
  697.             Fdiv                    ;         1 by zero !!
  698.             Fld     St              ; now make a
  699.             Fchs                    ;     negative infinity
  700.             Fcompp                  ; compare Ur two infinities
  701.             Fstsw   ControlW        ; if, for 8087 or 80287
  702.             Fwait                   ; til status word is put away
  703.             Push    Ax              ; save
  704.             Mov     Ax,ControlW     ; get control word
  705.             Sahf                    ; put AH into flags
  706.             Pop     Ax
  707.             Jnz     is80387         ; NO GOOD.... march on !!
  708.             Mov     Ax,287h         ; set 80287
  709.             Jmp     Short NdpExit
  710. is80387:
  711.             Mov     Ax,387h         ; must be an 80387
  712. NdpExit:
  713.             Pop     Bp              ; Restore Stack
  714.             Ret                     ; back to shadow
  715. GetNdp      ENDP
  716.  
  717. MSRValues   Db      2Ch, 28h, 2Dh, 29h, 2Ah, 2Eh, 1Eh, 2Ch
  718. LenMSRV     Equ     $-MSRValues
  719.  
  720. Message     Db      13,10
  721.             Db      9,'      Blank v1.2 - By Richard Wissinger - April 1989',13,10,'$'
  722. ResMsg      Db      9,9,'     Resident portion of Blank loaded',13,10,'$'
  723. TwoMons     Db      9,9,'     A second video adapter was found',13,10,'$'
  724. ParmPass    Db      9,9,'     New time passed to resident code',13,10,'$'
  725. TimeOut     Db      9,9,'     Screen timeout set for '
  726. Minute      Db        '5 minutes',13,10,'$'
  727. NotLoaded   Db      9,7,'       Blank could not be found in resident memory!',13,10,'$'
  728. Disabled    Db      9,9,'     Resident Blank has been disabled',13,10,'$'
  729.  
  730. WorkBuf     Equ     $               ; Work area for Video BIOS 1B/12
  731. Main        ENDP
  732.             END     Main
  733.